package yc.gg.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;
import yc.gg.constants.WechatConstants;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * \* User: Fuyue
 * \* Date: 2024/12/4
 * \* Description:
 * \
 */
@Slf4j
public class WechatUtils {
    public static JSONObject getSessionKeyOrOpenId(String code) {
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> requestUrlParam = new HashMap<>();
        // https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=164113089&lang=zh_CN
        requestUrlParam.put("appid", WechatConstants.APPID);
        requestUrlParam.put("secret", WechatConstants.SECRET);
        requestUrlParam.put("js_code", code);
        requestUrlParam.put("grant_type", "authorization_code");

        //调用微信接口获取openid
        JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));
        return jsonObject;
    }


    // 解密工具方法
    public static String decryptPhoneNumber(String sessionKey, String encryptedData, String iv) throws Exception {
        try {
            // 确保参数非空
            if (sessionKey == null || encryptedData == null || iv == null) {
                log.error("参数为空: sessionKey={}, encryptedData={}, iv={}", sessionKey, encryptedData, iv);
                throw new IllegalArgumentException("解密参数不能为空");
            }

            // Base64 解码
            byte[] keyBytes = Base64.getDecoder().decode(sessionKey);
            byte[] dataBytes = Base64.getDecoder().decode(encryptedData);
            byte[] ivBytes = Base64.getDecoder().decode(iv);

            // 验证密钥长度（AES-128 需要 16 字节，但微信 session_key 可能为 24 或 32 字节）
            if (keyBytes.length * 8 != 128 && keyBytes.length * 8 != 192 && keyBytes.length * 8 != 256) {
                log.error("无效的 session_key 长度: {} 位", keyBytes.length * 8);
                throw new IllegalArgumentException("session_key 长度不符合 AES 要求");
            }

            // 初始化 AES 解密
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));

            // 执行解密
            byte[] decrypted = cipher.doFinal(dataBytes);
            String decryptedStr = new String(decrypted, StandardCharsets.UTF_8);

            // 记录解密后的原始数据（敏感信息，生产环境建议关闭）
            log.debug("解密后的原始数据: {}", decryptedStr);

            // 解析 JSON
            JSONObject json = JSONObject.parseObject(decryptedStr);
            System.out.println(json);
            String phone = json.getString("purePhoneNumber");
            if (phone == null) {
                log.error("JSON 中缺少 purePhoneNumber 字段: {}", json);
                throw new RuntimeException("解密结果无效");
            }

            return json.getString("purePhoneNumber");
        } catch (JSONException e) {
            log.error("JSON 解析失败: {}", e.getMessage());
            throw new RuntimeException("解析手机号失败", e);
        } catch (IllegalArgumentException e) {
            log.error("Base64 解码失败: sessionKey={}, encryptedData={}, iv={}", sessionKey, encryptedData, iv);
            throw new RuntimeException("参数格式异常", e);
        } catch (Exception e) {
            log.error("解密过程中发生未知错误: {}", e.getMessage());
            throw e; // 重新抛出以保留堆栈信息
        }
    }
}
